#include "Sphere.h"

Sphere::Sphere(const Vector& _c, const fp _R)
{
  c = _c;
  R = _R;
  zNear = zFar = 0.0f;
};

Sphere::Sphere(const Sphere& s) { Sphere(s.c, s.R); };

bool Sphere::Intersect(const Ray& r)
{
  zNear = zFar = 0.0f;
  
  Vector o_minus_c(r.o);
  o_minus_c -= c;
  
	const fp a = r.d * r.d,								     // a = d^2
           p = (r.d * o_minus_c) * 2.0f,	   // p = 2d(o - c)
           q = o_minus_c * o_minus_c - R*R;  // q = (o - c)^2 - R^2

	fp discriminant = p*p - 4*a*q;						 // p^2 - 4aq

	// check the discriminant for being >= 0
	if (discriminant < 0) return false;

	// get the square root
	discriminant = sqrt(discriminant);

  // get graze/enter distance
  zNear = (-p - discriminant) / 2.0f*a;
  
  // get exit distance
  if (discriminant > 0)
    zFar = (-p + discriminant) / 2.0f*a;
  
  return true;
};
